package cn.xorange.commons.core.basic.controller;

import cn.hutool.core.util.ReflectUtil;
import cn.xorange.commons.core.basic.bean.PageBean;
import cn.xorange.commons.core.basic.bean.ResultBean;
import cn.xorange.commons.core.basic.service.IBaseService;
import cn.xorange.commons.data.core.entity.BaseEntity;
import cn.xorange.commons.data.core.entity.TreeEntity;
import cn.xorange.commons.data.utils.ParamUtil;
import cn.xorange.commons.exception.DataException;
import cn.xorange.commons.security.annotation.Authorize;
import cn.xorange.commons.utils.lang.ObjectUtils;
import cn.xorange.commons.utils.poi.excel.EasyExcelUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.Objects;

/**
 * @author : yangjian
 * @date : 2021/8/18
 * @description :
 */
public abstract class DataController<T extends BaseEntity,S extends IBaseService<T>>
        extends BaseController {

    @Autowired
    protected S service;

    @Authorize(hasPerm = "list")
    @GetMapping("/list")
    public PageBean list(T t){
        super.startPage();
        boolean has = ReflectUtil.hasField(t.getClass(),"sort");
        if(has){
            t.order.asc("sort");
        }
        List<T> list = this.service.getList(t);

        return new PageBean(list);
    }

    @Authorize(hasPerm = "list")
    @GetMapping("/allList")
    public ResultBean allList(T t){
        boolean has = ReflectUtil.hasField(t.getClass(),"sort");
        if(has){
            t.order.asc("sort");
        }
        return ResultBean.onSuccess(this.service.getList(t));
    }

    @Authorize(hasPerm = "export")
    @PostMapping("/export")
    public void export(HttpServletResponse response, @RequestBody T t) {
        List<T> list = this.service.getList(t);
        EasyExcelUtil.exportExcel(list,"导出","导出",t.getClass(),"用户导出",response);
    }

    @Authorize(hasPerm = "query")
    @GetMapping("/{id}")
    public ResultBean info(@PathVariable(value = "id") Long id){
        return ResultBean.onSuccess(this.service.getById(id));
    }

    @Authorize(hasPerm = "add")
    @PostMapping()
    @Transactional(rollbackFor = RuntimeException.class)
    public ResultBean add(@Validated @RequestBody T t){
        return ResultBean.onSuccess(this.service.add(t));
    }

    @Authorize(hasPerm = "edit")
    @PutMapping()
    @Transactional(rollbackFor = RuntimeException.class)
    public ResultBean update(@Validated @RequestBody T t){
        return ResultBean.onSuccess(this.service.update(t));
    }

    @Authorize(hasPerm = "edit")
    @PutMapping("/changeStatus")
    @Transactional(rollbackFor = RuntimeException.class)
    public ResultBean changeStatus(@RequestBody T t){
        this.service.changeStatus(t);
        return ResultBean.onSuccess();
    }


    @Authorize(hasPerm = "remove'")
    @DeleteMapping("/{id}")
    @Transactional(rollbackFor = RuntimeException.class)
    public ResultBean del(@PathVariable Long id) {
        ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
        Class<T> t = (Class<T>) pt.getActualTypeArguments()[0];
        T entity = ReflectUtil.newInstance(t.getName());
        if(entity instanceof TreeEntity){
            entity.where.equal("parentId", id);
            List<T> childSysMenus = this.service.getList(entity);
            if (!childSysMenus.isEmpty()){
                return ResultBean.onFail("请先删除子集");
            }
        }
        this.service.deleteById(id);
        return ResultBean.onSuccess();
    }

    //@Authorize(hasPerm = "remove'")
    //@DeleteMapping()
    //@Transactional(rollbackFor = RuntimeException.class)
    //public ResultBean del(@RequestBody T t) {
    //    Field keyField = ParamUtil.getKeyField(t.getClass());
    //    if(Objects.isNull(keyField)){
    //        throw DataException.entityKeyColNotFound();
    //    }else {
    //        String keyFieldName = keyField.getName();
    //        Object ids = t.getParams().get(keyFieldName);
    //        if (Objects.isNull(ids)){
    //            Object id = ParamUtil.getKeyValue(t);
    //            if(Objects.isNull(id)){
    //                throw DataException.dataKeyValueNull();
    //            }else {
    //                return ResultBean.onSuccess(this.service.delete(ObjectUtils.toLong(id)));
    //            }
    //        }else {
    //            List<Object> lst = ObjectUtils.toList(ids);
    //            Object[] objs = lst.toArray(new Object[lst.size()]);
    //            if(Objects.isNull(objs)){
    //                throw DataException.dataKeyValueNull();
    //            }else {
    //                return ResultBean.onSuccess(this.service.delete(objs));
    //            }
    //        }
    //    }
    //}





}
